﻿// ==============================================================================
// Copyright (c) 2012 Bndy.Net, All rights reserved.
// Created by Bndy on 4/4/2012 8:10:05 PM
//
//                    * * * * * * * * * * * * * 
//                    * MAIL- bndy5337@163.com *       http://www.bndy.net
//                    * Q Q - 81795705 =========================================>
//                    * MSN - bndy5337@msn.com *
//                    * * * * * * * * * * * * * 
//
// ------------------------------------------------------------------------------
// 
// ==============================================================================

using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using System.Configuration;

using Net.Bndy.Data;
using Net.Bndy.Framework.SqlBuilders;

namespace Net.Bndy.Framework
{
    public abstract class EntityBase
    {
        protected IDbFactory _dbFactory;
        public virtual IDbFactory DbFactory
        {
            set
            {
                _dbFactory = value;
            }
            get
            {
                if(_dbFactory == null)
                    _dbFactory = new MsSqlFactory(ConfigurationManager.ConnectionStrings[0].ConnectionString);

                return _dbFactory;
            }
        }

        private SqlBuilder SqlBuilder
        {
            get
            {
                return SqlBuilder.CreateBuilder(this._dbFactory);
            }
        }

        public virtual bool Add()
        {
            bool result = false;

            result = this.DbFactory.ExecuteCommand(this.SqlBuilder.Insert(this)) > 0;

            return result;
        }

        public virtual bool Modify()
        {
            bool result = false;

            result = this.DbFactory.ExecuteCommand(this.SqlBuilder.Update(this)) > 0;

            return result;
        }

        public virtual bool Remove()
        {
            bool result = false;

            result = this.DbFactory.ExecuteCommand(this.SqlBuilder.Delete(this)) > 0;

            return result;
        }

        #region Internal Mehtods
        internal Dictionary<string, object> GetAllPropertyValuePair()
        {
            Dictionary<string, object> result = new Dictionary<string, object>();

            foreach (PropertyInfo pi in this.GetType().GetProperties())
            {
                if (pi.PropertyType.Equals(typeof(string)) || pi.PropertyType.IsValueType)
                {
                    if (pi.GetCustomAttributes(typeof(AutoIncreaseAttribute), false).Count() == 0 &&
                        pi.GetCustomAttributes(typeof(VirtualAttribte), false).Count() == 0)
                    {
                        result.Add(pi.Name, pi.GetValue(this, null));
                    }
                }
            }

            return result;
        }

        internal Dictionary<string, object> GetPropertyValuePairWithoutPrimaryKey()
        {
            Dictionary<string, object> result = this.GetAllPropertyValuePair();
            KeyValuePair<string, object>? primaryKey = this.GetPrimaryKey();

            if (primaryKey.HasValue)
                result.Remove(this.GetPrimaryKey().Value.Key);

            return result;
        }

        internal KeyValuePair<string, object>? GetPrimaryKey()
        {
            KeyValuePair<string, object>? result = null;

            foreach (PropertyInfo pi in this.GetType().GetProperties())
            {
                if (pi.GetCustomAttributes(typeof(PrimaryKeyAttribute), false).Count() > 0)
                {
                    result = new KeyValuePair<string, object>(
                        pi.Name,
                        pi.GetValue(this, null)
                        );
                }
            }

            return result;
        }
        #endregion
    }
}
